// (c) Copyright 2013 Mike Riedel.
// This source is subject to the Microsoft Public License (Ms-PL).
// All other rights reserved.

using System.Diagnostics;
using FreshMeat.MiniHsm;

namespace FreshMeat.MiniHsmTest
{
   [DebuggerDisplay("Light={Light}, Heat={Heat}, State={CurrentState}")]
   internal class Oven : MiniMachine<Oven.Input>
   {
      public enum Input
      {
         GetParent = -4,
         SetDefault,
         Enter,
         Exit,
         PushedStart,
         PushedStop,
         OpenedDoor,
         ClosedDoor,
         TimerExpired,
      }

      public Oven()
         : base(Input.GetParent, Input.SetDefault, Input.Enter, Input.Exit)
      {
         DefaultTo(Idle);
      }

      public void Update(Input input)
      {
         Process(input);
      }

      State Idle(Input input)
      {
         switch (input)
         {
            case Input.PushedStart:
               TransitionTo(Cooking);
               return null;

            case Input.OpenedDoor:
               TransitionTo(IdleOpen);
               return null;
         }

         return Root;
      }

      State IdleOpen(Input input)
      {
         switch (input)
         {
            case Input.Enter:
               Light = true;
               return null;

            case Input.Exit:
               Light = false;
               return null;

            case Input.ClosedDoor:
               TransitionTo(Idle);
               return null;
         }

         return Root;
      }

      State Cooking(Input input)
      {
         switch (input)
         {
            case Input.Enter:
               Light = true;
               Heat = true;
               return null;

            case Input.Exit:
               Light = false;
               Heat = false;
               return null;

            case Input.PushedStop:
               TransitionTo(Idle);
               return null;

            case Input.OpenedDoor:
               TransitionTo(CookingOpen);
               return null;

            case Input.TimerExpired:
               TransitionTo(Idle);
               return null;
         }

         return Root;
      }

      State CookingOpen(Input input)
      {
         switch (input)
         {
            case Input.Enter:
               Light = true;
               return null;

            case Input.Exit:
               Light = false;
               return null;

            case Input.PushedStop:
               TransitionTo(IdleOpen);
               return null;

            case Input.ClosedDoor:
               TransitionTo(Cooking);
               return null;
         }

         return Root;
      }

      public bool Light { get; private set; }
      public bool Heat { get; private set; }
   }
}